Indicador 1 - Estabelecimentos hospitalares já existentes com ampliação de leitos covid-19

Instrução: Estabelecimento anteriores a 2020, com registro de leitos covid-19 (com as Descrições: “51-UTI II ADULTO-SINDROME RESP. AGUDA GRAVE (SRAG)-COVID-19” ou “52”- UTI II PEDIATRICA-SINDROME RESP. AGUDA GRAVE (SRAG)-COVID-19” ou “96- SUPORTE VENTILATÓRIO PULMONAR - COVID-19”).

Baixando os dados

Primeiramente, preciso saber quais eram os estabelecimentos que já existiam em 2019. Para feitos de análise, foram acessados os estabelecimentos nas competências 12 (Dezembro) de 2019.

cnes_2019 <- df %>% 
  filter(COMPETEN == "201912") %>% 
  distinct(CNES, FANTASIA, RAZ_SOCI)

cnes_2019c <- cnes_2019$CNES  


leitos <- c(51, 52, 96)

cnes_20_21_exist <- df %>% 
  filter(COMPETEN == "202012" | COMPETEN == "202112") %>% 
  filter(CNES %in% cnes_2019c) %>% 
  filter(CODLEITO %in% leitos) %>% 
  mutate(tipo_hospital = "Hospitais existentes") %>% 
  group_by(COMPETEN, tipo_hospital, uf, municipio_pad, regiao,  CNES, FANTASIA) %>% 
  summarise(qtd_leitos = sum(QT_EXIST)) %>% 
  janitor::clean_names()

Os estabelecimentos que cumprem os requisitos estão listados abaixo.

Temos a seguinte situação em termos de leitos no último mês de 2020 e 2021, respectivamente.

c <- cnes_20_21_exist %>% 
  mutate(Ano = as.integer(substr(competen, 1, 4))) %>% 
  group_by(Ano, regiao) %>% 
  summarise(qtd_leitos = sum(qtd_leitos)) %>% 
  ggplot(aes(x = Ano, y = qtd_leitos, fill = regiao)) + geom_col(position="dodge") + 
  scale_x_continuous(breaks = seq(2020,2021,1)) +
  theme_minimal() + ylab("Quantidade existente") + ggtitle("Quantidade de leitos existentes em dezembro de cada ano por região",
                                                           "Fonte: CNES-LT")

  
  
plotly::ggplotly(c)  

O próximo passo é identificar quantos hospitais que já existiam em 2019 e tinham leitos covid em 2020 e 2021.

cnes20 <- cnes_20_21_exist %>% 
  filter(competen == "202012") %>% 
  distinct(cnes, fantasia, uf, regiao) %>% 
  group_by(regiao, uf, municipio_pad) %>% 
  summarise(total = n()) %>% 
  mutate(ano = 2020)
   
  
cnes20_c <- cnes_20_21_exist %>% 
              filter(competen == "202012") %>% 
              distinct(cnes)

cnes20_c <- cnes20_c$cnes


cnes21 <- cnes_20_21_exist %>% 
            filter(competen == "202112") %>% 
            #filter(cnes %ni% cnes20_c) %>% 
            distinct(cnes, fantasia, uf, regiao) %>% 
            group_by(regiao, uf, municipio_pad) %>% 
            summarise(total = n()) %>% 
            mutate(ano = 2021)

cnes_exist <- rbind(cnes20, cnes21)

d <- cnes_exist %>% 
      group_by(regiao, ano) %>% 
      summarise(total = sum(total)) %>% 
      ggplot(aes(x = ano, y = total, fill = regiao)) + geom_col(position = "dodge") +  
      theme_minimal() +  scale_x_continuous(breaks = seq(2020,2021,1)) + 
      ylab("Quantidade de estabelecimentos") + ggtitle("Quantidade de estabelecimentos existentes em 2019 em cada ano")

plotly::ggplotly(d)
#writexl::write_xlsx(cnes_exist, "01_estabelecimentos_exist.xlsx")

Indicador 2 - Estabelecimentos hospitalares novos com estrutura (serviços) para covid-19

Instrução: Estabelecimentos criados entre 2020 e 2021, com o termo “COVID” em seu nome fantasia e (+) aqueles com leito com as descrições: “51-UTI II ADULTO-SINDROME RESP. AGUDA GRAVE (SRAG)-COVID-19” ou “52 - UTI II PEDIATRICA-SINDROME RESP. AGUDA GRAVE (SRAG)-COVID-19” ou “96- SUPORTE VENTILATÓRIO PULMONAR - COVID-19”).

Primeiramente, preciso saber quais eram os estabelecimentos que foram criados nos anos de 2020 e 2021. Para isso, vou excluir todos os estabelecimentos que já existiam em 2019, pegando apenas os novos os anos subsequentes.

Para efeitos de análise, foram acessados os estabelecimentos nas competências 12 (Dezembro) de cada ano.

cnes_2019 <- df %>% 
  filter(COMPETEN == "201912") %>% 
  distinct(CNES, FANTASIA, RAZ_SOCI)

cnes_2019c <- cnes_2019$CNES  


leitos <- c(51, 52, 96)

cnes_20_21_novos <- df %>% 
  filter(COMPETEN == "202012" | COMPETEN == "202112") %>% 
  filter(CNES %ni% cnes_2019c) %>% 
  mutate(tipo_hospital = "Hospitais existentes") %>% 
  filter(str_detect(FANTASIA, "covid") | CODLEITO %in% leitos) %>% 
  group_by(COMPETEN, tipo_hospital, uf, municipio_pad, regiao,  CNES, FANTASIA) %>% 
  summarise(qtd_leitos = sum(QT_EXIST)) %>% 
  janitor::clean_names()
# writexl::write_xlsx(cnes_20_21_novos, "02_leitos_hospitais_novos.xlsx")

Os estabelecimentos que cumprem os requisitos estão listados abaixo.

Temos a seguinte situação em termos de leitos no último mês de 2020 e 2021 respectivamente.

a <- cnes_20_21_novos %>% 
  mutate(Ano = as.integer(substr(competen, 1, 4))) %>% 
  group_by(Ano, regiao) %>% 
  summarise(qtd_leitos = sum(qtd_leitos)) %>% 
  ggplot(aes(x = Ano, y = qtd_leitos, fill = regiao)) + geom_col(position = "dodge") + 
  scale_x_continuous(breaks = seq(2020,2021,1)) +
  theme_minimal() + ylab("Quantidade existente") + ggtitle("Quantidade de leitos existentes",
                                                           "Fonte: CNES-LT")

  
  
plotly::ggplotly(a)  

O próximo passo é identificar quantos hospitais novos foram criados cada ano

cnes20 <- cnes_20_21_novos %>% 
  filter(competen == "202012") %>% 
  distinct(cnes, fantasia, uf, regiao) %>% 
  group_by(regiao, uf, municipio_pad) %>% 
  summarise(total = n()) %>% 
  mutate(ano = 2020)
   
  
cnes20_c <- cnes_20_21_novos %>% 
              filter(competen == "202012") %>% 
              distinct(cnes)

cnes20_c <- cnes20_c$cnes


cnes21 <- cnes_20_21_novos %>% 
            filter(competen == "202112") %>% 
            filter(cnes %ni% cnes20_c) %>% 
            distinct(cnes, fantasia, uf, regiao) %>% 
            group_by(regiao, uf, municipio_pad) %>% 
            summarise(total = n()) %>% 
            mutate(ano = 2021)

cnes_novos <- rbind(cnes20, cnes21)

b <- cnes_novos %>% 
      group_by(ano, regiao) %>% 
      summarise(total = sum(total)) %>% 
      ggplot(aes(x = ano, y = total, fill = regiao)) + geom_col(position = "dodge") +  
      theme_minimal() +  scale_x_continuous(breaks = seq(2020,2021,1)) + 
      ylab("Quantidade de estabelecimentos") + ggtitle("Quantidade de estabelecimentos novos em cada ano",
                                                       "Fonte: CNES-LT")

plotly::ggplotly(b)

O gráfico acima apresenta o total de estabelecimentos criados segundo as instruções do indicador nos últimos dois anos.

Indicador 3 - Respiradores cadastrados nos estabelecimento hospitalares já existentes

Instruções: não há instrução para este indicador. Suponho que neste caso, precisamos contabilizar o total por hospitais que já existiam, alinhado ao indicador 1. O respirador é um equipamento cujo código é 64.

df3 <- sqlQuery(channel, 'SELECT a.COMPETEN, a.CNES, a.CODUFMUN, municipio_pad, a.uf, regiao, SUM(QT_EXIST) AS QTD  
                          FROM Dados.cnes.EQ a
                          LEFT JOIN "Analytics Layer".Territorial."Municípios - Hierarquia Completa" c
                                                  ON CAST(a.CODUFMUN AS INT) = c.cod_municipio
                          WHERE CAST(CODEQUIP AS INT) = 64
                          GROUP BY CNES, CODUFMUN, COMPETEN, municipio_pad, a.uf, regiao')

Vamos pegar os mesmos estabelecimentos que filtramos no indicador 1.

df3_t <- df3 %>% 
  filter(CNES %in% cnes_2019c) %>% 
  mutate(mes_ano = lubridate::ym(COMPETEN),
         ano = lubridate::year(mes_ano)) %>% 
  group_by(regiao, uf, municipio_pad, mes_ano, ano) %>% 
  summarise(total = sum(QTD)) %>% 
  filter(mes_ano > "2019-12-01")

DT::datatable(df3_t)
e <- df3_t %>% 
  group_by(mes_ano, regiao) %>% 
  summarise(total = sum(total)) %>% 
  ggplot(aes(x = mes_ano, y = total, col = regiao)) + geom_line() + 
  facet_wrap(~regiao, scales = "free_y") + theme_minimal() +
  scale_x_date(date_breaks = "1 year") + theme(legend.position="none")


plotly::ggplotly(e)

Em média, por ano tínhamos a seguinte distribuição por município

respiradores_hosp_existentes <- df3_t %>% 
  janitor::clean_names() %>% 
  group_by(ano, regiao, uf, municipio_pad) %>% 
  summarise(total = round(mean(total),2))

# writexl::write_xlsx(respiradores_hosp_existentes, "05_respiradores_hosp_existentes.xlsx")

Indicador 4 - Respiradores cadastrados nos estabelecimentos hospitalares já existentes NOVOS PARA COVID

Vamos levantar o número de respiradores naqueles estabelecimentos que incluíram leitos covid apenas a partir de 2020, conforme extraído no indicador 2.

df_4 <- df3 %>% 
  filter(CNES %ni% cnes_2019c) %>% 
  mutate(mes_ano = lubridate::ym(COMPETEN),
         ano = lubridate::year(mes_ano)) %>% 
  group_by(regiao, uf, municipio_pad, ano, mes_ano) %>% 
  summarise(total = sum(QTD)) %>% 
  filter(mes_ano > "2019-12-01") 

DT::datatable(df_4)
f <- df_4 %>% 
  group_by(mes_ano, regiao) %>% 
  summarise(total = sum(total)) %>% 
  ggplot(aes(x = mes_ano, y = total, col = regiao)) + geom_line() + 
  facet_wrap(~regiao, scales = "free_y") + theme_minimal() +
  scale_x_date(date_breaks = "1 year") + theme(legend.position="none")


plotly::ggplotly(f)

Em média, por ano tínhamos a seguinte distribuição por município

respiradores_hosp_novos <- df_4 %>% 
  janitor::clean_names() %>% 
  group_by(ano, regiao, uf, municipio_pad) %>% 
  summarise(total = round(mean(total),2))

 # writexl::write_xlsx(respiradores_hosp_novos, "06_respiradores_hosp_novos.xlsx")

Indicador 5 - Internação em UTI covid-19 por estabelecimento de saúde, conforme os indicadores apontados nas linhas 1 e 2 acima

Os seguintes código CID-10 foram utilizados para buscar os casos de covid-19, conforme recomendação de preenchimento para morbimortalidade do Guia de Vigilância Epidemiológica: Emergência de Saúde Pública de Importância Nacional pela Doença pelo Coronavírus 2019 - Covid-19, versão 4, 2022.

Diagnóstico + B34.2 - Infecção por coronavírus de localização não especificada + U07.1 - covid-19, vírus identificado. É atribuído a um diagnóstico da covid-19 confirmada por testes de laboratório + U07.2 (covid-19, vírus não identificado, clínico-epidemiológico. É atribuído a um diagnóstico clínico ou epidemiológico da covid-19, em que a confirmação laboratorial é inconclusiva ou não está disponível).

Os códigos U07.1 (covid-19, vírus identificado) e U07.2 (covid-19, vírus não identificado, clínico-epidemiológico), definidos pela Organização Mundial de Saúde (OMS), são os marcadores da pandemia no Brasil, devendo sempre vir após o código B34.2, na mesma linha.

Condições pós-COVID-19 + B94.8 (sequelas de outras doenças infecciosas e parasitárias especificadas). + U09.9 (condição de saúde posterior à covid-19, não especificada) + M30.3 (síndrome de linfonodos mucocutâneos – Kawasaki). + U10.9 (síndrome inflamatória multissistêmica associada à covid-19, não especificada)

Vacinação e evento adverso à vacina COVID + Y59.0 (vacinas antivirais) e T88.7 (efeito adverso não especificado de droga ou medicamento) + U12.9 (vacinas contra a covid-19 que causam efeitos adversos com finalidade terapêutica, não especificada)

Reincidência de COVID-19 + B34.2 (infecção pelo coronavírus de localização não especificada) + U92.1 (reincidência de covid-19, confirmada)

Buscamos todas as observações cujo diagnóstico principal OU secundário fossem dos CID-10 indicados acima.

Selecionamos apenas as internações em UTI.

Obs.: As observações agregadas a nível município se referem ao município do estabelecimento de saúde e não o município de residência do paciente.

internacoes <- 
  sqlQuery(channel, "SELECT ANO_CMPT, MES_CMPT, UF_ZI, MUNIC_RES, DT_INTER, DT_SAIDA, DIAS_PERM, 
       MORTE, DIAG_PRINC, DIAG_SECUN, CID_ASSO, CID_MORTE, uf, competencia, MARCA_UTI,
       CNES
                    FROM Dados.sih.RD
                    WHERE substr(DT_INTER, 1, 4) > 2019 AND 
                          (DIAG_PRINC = 'B342' OR DIAG_PRINC = 'U071'
                          OR DIAG_PRINC = 'U072' OR DIAG_PRINC = 'B948'
                          OR DIAG_PRINC = 'U099' OR DIAG_PRINC = 'M303'
                          OR DIAG_PRINC = 'U109' OR DIAG_PRINC = 'Y590'
                          OR DIAG_PRINC = 'U129' OR DIAG_PRINC = 'U921'
                          OR DIAG_SECUN = 'B342' OR DIAG_SECUN = 'U071'
                          OR DIAG_SECUN = 'U072' OR DIAG_SECUN = 'B948'
                          OR DIAG_SECUN = 'U099' OR DIAG_SECUN = 'M303'
                          OR DIAG_SECUN = 'U109' OR DIAG_SECUN = 'Y590'
                          OR DIAG_SECUN = 'U129' OR DIAG_SECUN = 'U921') ", as.is = TRUE)


municipios <- 
  sqlQuery(channel, 'SELECT * FROM "Analytics Layer".Territorial."Municípios - Hierarquia Completa"', 
           as.is = TRUE) %>% 
  select(cod_municipio, municipio_pad)

municipios$cod_municipio <- as.integer(municipios$cod_municipio)

Cadger <- read_csv("~/GitHub/bases_uteis_saude/Cadger.csv", 
    locale = locale(encoding = "ISO-8859-1", 
        asciify = TRUE))

internacoes_t <- 
  internacoes %>% 
  left_join(Cadger, by = c("CNES"="CNES")) %>% 
  janitor::clean_names() %>% 
  left_join(municipios, by = c("codufmun"="cod_municipio")) %>% 
  mutate(marca_uti = as.integer(marca_uti)) %>% 
  filter(marca_uti > 73 & marca_uti < 87 | marca_uti == 99)

todas_internacoes <- 
  internacoes %>% 
  left_join(Cadger, by = c("CNES"="CNES")) %>% 
  janitor::clean_names() %>% 
  left_join(municipios, by = c("codufmun"="cod_municipio"))

Fazendo uma análise exploratória rápida dos dados, observa-se que a maioria dos casos foram registrados sob o CID-10 B342.

internacoes_t %>% 
  group_by(diag_princ) %>% 
  count()
## # A tibble: 4 x 2
## # Groups:   diag_princ [4]
##   diag_princ     n
##   <chr>      <int>
## 1 B342       74601
## 2 B948           1
## 3 M303          62
## 4 U109           1

Também vemos que a coluna diagnóstico secundário não foi preenchida nenhuma vez.

internacoes_t %>% 
  group_by(diag_secun) %>% 
  count()
## # A tibble: 1 x 2
## # Groups:   diag_secun [1]
##   diag_secun     n
##   <chr>      <int>
## 1 0000       74665

Vamos pegar o número de internações por mês conforme as condições listadas nos itens 1 e 2.

internacoes_hospitais_exist <-
  internacoes_t %>% 
  janitor::clean_names() %>% 
  mutate(mes_ano = substr(dt_inter, 1, 6),
         mes_ano = lubridate::ym(mes_ano),
         ano = lubridate::year(mes_ano)) %>% 
  filter(cnes %in% cnes_2019c) %>% 
  group_by(ano, mes_ano, uf, cnes, fantasia, municipio_pad) %>% 
  summarise(total = n()) %>% 
  mutate(tipo_hosp = "hospitais existentes")


internacoes_hospitais_novos <- 
  internacoes_t %>% 
  janitor::clean_names() %>% 
  mutate(mes_ano = substr(dt_inter, 1, 6),
         mes_ano = lubridate::ym(mes_ano),
         ano = lubridate::year(mes_ano)) %>% 
  filter(cnes %ni% cnes_2019c) %>% 
  group_by(ano, mes_ano, uf, cnes, fantasia, municipio_pad) %>% 
  summarise(total = n()) %>% 
  mutate(tipo_hosp = "hospitais novos")


internacoes_total <- rbind(internacoes_hospitais_exist, internacoes_hospitais_novos)

g <- internacoes_total %>% 
  group_by(ano, tipo_hosp) %>% 
  summarise(total_internacoes = sum(total)) %>% 
  ggplot(aes(x = ano, y = total_internacoes,
             fill = tipo_hosp)) + geom_col(position = "dodge") + 
  theme_minimal()

plotly::ggplotly(g)

Acessado o total de nascimentos por município, tem-se:

internacoes_total <- 
  internacoes_total %>% 
  group_by(ano, uf, municipio_pad, tipo_hosp) %>% 
  summarise(total_internacoes = sum(total))

# writexl::write_xlsx(internacoes_total, "07_internacoes.xlsx")

##Indicador 6: Mortalidade por covid-19 em UTI Covid-19 por estabelecimento de saúde, conforme os indicadores apontados nas linhas 1 e 2 acima

obitos_hospitais_exist <-
  internacoes_t %>% 
  janitor::clean_names() %>% 
  filter(morte == 1) %>% 
  mutate(mes_ano = substr(dt_inter, 1, 6),
         mes_ano = lubridate::ym(mes_ano),
         ano = lubridate::year(mes_ano)) %>% 
  filter(cnes %in% cnes_2019c) %>% 
  group_by(ano, mes_ano, uf, cnes, fantasia, municipio_pad) %>% 
  summarise(total = n()) %>% 
  mutate(tipo_hosp = "hospitais existentes")



obitos_hospitais_novos <- 
  internacoes_t %>% 
  janitor::clean_names() %>% 
  filter(morte == 1) %>% 
  mutate(mes_ano = substr(dt_inter, 1, 6),
         mes_ano = lubridate::ym(mes_ano),
         ano = lubridate::year(mes_ano)) %>% 
  filter(cnes %ni% cnes_2019c) %>% 
  group_by(ano, mes_ano, uf, cnes, fantasia, municipio_pad) %>% 
  summarise(total = n()) %>% 
  mutate(tipo_hosp = "hospitais novos")


obitos_total <- rbind(obitos_hospitais_exist, obitos_hospitais_novos)

h <- obitos_total %>% 
  group_by(ano, tipo_hosp) %>% 
  summarise(total_obitos = sum(total)) %>% 
  ggplot(aes(x = ano, y = total_obitos,
             fill = tipo_hosp)) + geom_col(position = "dodge") + 
  theme_minimal()

plotly::ggplotly(h)

O gráfico acima apresenta as internações que tiveram óbito como desfecho.

obitos_total <- 
obitos_total %>% 
  group_by(ano, tipo_hosp, uf, municipio_pad) %>% 
  summarise(total_obitos = sum(total))

# writexl::write_xlsx(obitos_total, "08_obitos_internacoes.xlsx")

##Média de duração da internação em UTI Covid-19, por estabelecimento de saúde, conforme os indicadores apontados nas linhas 1 e 2 acima

dias_hospitais_exist <-
  todas_internacoes %>% 
  janitor::clean_names() %>% 
  mutate(mes_ano = substr(dt_inter, 1, 6),
         mes_ano = lubridate::ym(mes_ano),
         ano = lubridate::year(mes_ano)) %>% 
  filter(cnes %in% cnes_2019c) %>% 
  group_by(ano, uf, municipio_pad) %>% 
  summarise(dias_medios = round(mean(dias_perm),2)) %>% 
  mutate(tipo_hosp = "hospitais existentes")

dias_hospitais_novos <- 
  todas_internacoes %>% 
  janitor::clean_names() %>% 
  mutate(mes_ano = substr(dt_inter, 1, 6),
         mes_ano = lubridate::ym(mes_ano),
         ano = lubridate::year(mes_ano)) %>% 
  filter(cnes %ni% cnes_2019c) %>% 
  group_by(ano, uf, municipio_pad) %>% 
  summarise(dias_medios = round(mean(dias_perm),2)) %>% 
  mutate(tipo_hosp = "hospitais novos")

media_dias_hospitais <- rbind(dias_hospitais_exist, 
                              dias_hospitais_novos)

gi_exist <- 
  todas_internacoes %>% 
  janitor::clean_names() %>% 
  mutate(mes_ano = substr(dt_inter, 1, 6),
         mes_ano = lubridate::ym(mes_ano),
         ano = lubridate::year(mes_ano)) %>% 
  filter(cnes %in% cnes_2019c) %>% 
  group_by(ano) %>% 
  summarise(dias_medios = round(mean(dias_perm),2)) %>% 
  mutate(tipo_hosp = "hospitais existentes")

gi_novos <- 
  todas_internacoes %>% 
  janitor::clean_names() %>% 
  mutate(mes_ano = substr(dt_inter, 1, 6),
         mes_ano = lubridate::ym(mes_ano),
         ano = lubridate::year(mes_ano)) %>% 
  filter(cnes %ni% cnes_2019c) %>% 
  group_by(ano) %>% 
  summarise(dias_medios = round(mean(dias_perm),2)) %>% 
  mutate(tipo_hosp = "hospitais novos")

gi <- rbind(gi_novos, gi_exist)

i <- gi %>% 
  ggplot(aes(x = ano, y = dias_medios,
             fill = tipo_hosp)) + geom_col(position = "dodge") + 
  theme_minimal()

plotly::ggplotly(i)

Observa-se que, em média, tivemos médias muito próximas, por volta de 8 dias.

# writexl::write_xlsx(media_dias_hospitais, "09_media_internacao.xlsx")